package com.tengju.support.domain.model.message;

import com.tengju.support.domain.model.resource.StarLevel;
import com.tengju.support.domain.shared.DomainException;
import com.tengju.support.domain.shared.DomainExceptionCode;
import lombok.Value;
import lombok.experimental.NonFinal;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Value
public class MessageTask {

    @NonFinal
    TaskId taskId;
    @NonFinal
    String title;

    MessageChannel messageChannel;
    @NonFinal
    MessageType messageType;
    @NonFinal
    MessageContentType contentType;
    @NonFinal
    String imgUrl;
    @NonFinal
    String content;
    @NonFinal
    String jumpUrl;
    @NonFinal
    MessageUserOrientation messageUserOrientation;
    @NonFinal
    Boolean push;

    @NonFinal
    SendStatus sendStatus;

    String createBy;
    @NonFinal
    String updateBy;
    @NonFinal
    LocalDateTime sendTime;
    LocalDateTime createTime;
    LocalDateTime updateTime;

    //
    //              ｜------>发送中--------|
    //    未发送-----｜                    |---------->已发送
    //              ｜--------------------|
    //
    public void changeSendStatus(SendStatus afterStatus) {

        if (sendStatus == SendStatus.NOT_SEND &&
                (afterStatus == SendStatus.SENDING || afterStatus == SendStatus.SEND)) {
            this.sendStatus = afterStatus;
        } else if (sendStatus == SendStatus.SENDING && afterStatus == SendStatus.SEND) {
            this.sendStatus = afterStatus;
        } else {
            throw DomainException.error(DomainExceptionCode.STATUS_CHANGE_ERROR);
        }

    }

    public void update(String title, MessageType messageType, MessageContentType messageContentType, String imgUrl, String content, String jumpUrl, OrientationType orientationType, List<Long> orientationObjectList, Boolean push, SendStatus sendStatus, LocalDateTime sendTime, String updateBy) {
        if (StringUtils.isEmpty(title)) {
            throw DomainException.error(DomainExceptionCode.MESSAGE_TITLE_EMPTY);
        }
        if (messageType == null) {
            throw DomainException.error(DomainExceptionCode.MESSAGE_TYPE_EMPTY);
        }
        if (messageContentType == null) {
            throw DomainException.error(DomainExceptionCode.MESSAGE_CONTENT_TYPE_EMPTY);
        }
        if (orientationType == null) {
            throw DomainException.error(DomainExceptionCode.MESSAGE_ORIENTATION_TYPE_EMPTY);
        }
        if (push == null) {
            throw DomainException.error(DomainExceptionCode.MESSAGE_PUSH_EMPTY);
        }
        if (sendTime == null) {
            throw DomainException.error(DomainExceptionCode.MESSAGE_SEND_TIME_EMPTY);
        }
        if (LocalDateTime.now().compareTo(sendTime) >= 0){
            throw DomainException.error(DomainExceptionCode.MESSAGE_SEND_TIME_ERROR);
        }
        List<Object> orientationObject = new ArrayList<>();
        if (OrientationType.DESIGNATED_USER == orientationType) {
            if (CollectionUtils.isEmpty(orientationObjectList)){
                throw DomainException.error(DomainExceptionCode.MESSAGE_ORIENTATION_USER_EMPTY_ERROR);
            }
            orientationObjectList = orientationObjectList.stream()
                    .filter(o -> {
                        if (0L >= o){
                            throw DomainException.error(DomainExceptionCode.MESSAGE_ORIENTATION_ZERO_ERROR);
                        }
                        return true;
                    })
                    .distinct()
                    .collect(Collectors.toList());
            orientationObject = Arrays.asList(orientationObjectList.toArray());
        } else if (OrientationType.DESIGNATED_STAR_LEVEL == orientationType){
            if (CollectionUtils.isEmpty(orientationObjectList)){
                throw DomainException.error(DomainExceptionCode.MESSAGE_ORIENTATION_LEVEL_EMPTY_ERROR);
            }
            orientationObjectList = orientationObjectList.stream()
                    .filter(o -> {
                        if (StarLevel.parseByCode(o.intValue()) == null){
                            throw DomainException.error(DomainExceptionCode.MESSAGE_ORIENTATION_LEVEL_ERROR);
                        }
                        return true;
                    })
                    .distinct()
                    .collect(Collectors.toList());
            orientationObject = Arrays.asList(orientationObjectList.toArray());
        }
        this.title = title;
        this.messageType = messageType;
        this.contentType = messageContentType;
        this.imgUrl = imgUrl;
        this.content = content;
        this.jumpUrl = jumpUrl;
        this.messageUserOrientation = new MessageUserOrientation(orientationType, orientationObject);
        this.push = push;
        this.sendStatus = sendStatus;
        this.updateBy = updateBy;
        this.sendTime = sendTime;
    }

    public void generateMessageId(TaskId messageId) {
        this.taskId = messageId;
    }
}
